﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Security.Cryptography;
using System.Text;

namespace ZHello.Utils
{
    /// <summary>
    /// 随机类型
    /// </summary>
    [Flags]
    public enum RandomType
    {
        /// <summary>
        /// 未知
        /// </summary>
        [Description("未知")]
        None = 0,

        /// <summary>
        /// 数字
        /// </summary>
        [Description("数字")]
        Number = 1 << 0,

        /// <summary>
        /// 字母
        /// </summary>
        [Description("字母")]
        Alphabet = 1 << 1,

        /// <summary>
        /// 中文
        /// </summary>
        [Description("中文")]
        Chinese = 1 << 2,

        /// <summary>
        /// 特定
        /// </summary>
        [Description("特定")]
        Special = 1 << 3,
    }

    /// <summary>
    /// 特定随机类型
    /// </summary>
    internal enum RandomSpecialType
    {
        /// <summary>
        /// 手机号
        /// </summary>
        [Description("手机号")]
        CellPhoneNumber = 1,

        /// <summary>
        /// 身份证号
        /// </summary>
        [Description("身份证号")]
        IdentNumber = 2,

        /// <summary>
        /// 中文姓名
        /// </summary>
        [Description("中文姓名")]
        ChineseName = 3,
    }

    internal static class RExtensions
    {
        /// <summary>
        /// 类型描述信息缓存
        /// </summary>
        private static Dictionary<Type, string> TypeDescDic { get; set; }

        /// <summary>
        /// 是否含有指定状态
        /// </summary>
        /// <param name="rtype"></param>
        /// <param name="ltype"></param>
        /// <returns></returns>
        public static bool Contains(this RandomType rtype, RandomType ltype)
        {
            return (rtype & ltype) != 0;
        }

        /// <summary>
        /// 获取指定枚举值的描述信息
        /// </summary>
        /// <param name="enumObj"></param>
        /// <returns></returns>
        public static string EnumDescription(this ValueType enumObj)
        {
            if (enumObj.GetType().IsEnum)
            {
                string value = enumObj.ToString();
                FieldInfo field = enumObj.GetType().GetField(value);
                object[] objs = field.GetCustomAttributes(typeof(DescriptionAttribute), false);
                if (objs == null || objs.Length == 0)
                    return "";
                var des = (DescriptionAttribute)objs[0];
                return des.Description;
            }
            return null;
        }

        /// <summary>
        /// 获取类型Description特性信息
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static string TypeDescription(this object obj)
        {
            if (obj == null)
            {
                return null;
            }
            if (TypeDescDic != null && TypeDescDic.ContainsKey(obj.GetType()))
            {
                return TypeDescDic[obj.GetType()];
            }
            var attrs = obj.GetType().GetCustomAttributes(typeof(DescriptionAttribute), false);
            if (attrs != null && attrs.Length != 0)
            {
                if (TypeDescDic == null)
                {
                    TypeDescDic = new Dictionary<Type, string>();
                }
                var str = ((DescriptionAttribute)attrs[0]).Description;
                if (!TypeDescDic.ContainsKey(obj.GetType()))
                {
                    TypeDescDic.Add(obj.GetType(), str);
                }
                return str;
            }
            return null;
        }
    }

    internal class RandomGeneratorUtil
    {
        /// <summary>
        /// 姓氏集合
        /// </summary>
        private static List<string> Surnames = new List<string>() {
  "赵", "钱", "孙", "李", "周", "吴", "郑", "王", "冯", "陈", "楮", "卫", "蒋", "沈", "韩", "杨",
  "朱", "秦", "尤", "许", "何", "吕", "施", "张", "孔", "曹", "严", "华", "金", "魏", "陶", "姜",
  "戚", "谢", "邹", "喻", "柏", "水", "窦", "章", "云", "苏", "潘", "葛", "奚", "范", "彭", "郎",
  "鲁", "韦", "昌", "马", "苗", "凤", "花", "方", "俞", "任", "袁", "柳", "酆", "鲍", "史", "唐",
  "费", "廉", "岑", "薛", "雷", "贺", "倪", "汤", "滕", "殷", "罗", "毕", "郝", "邬", "安", "常",
  "乐", "于", "时", "傅", "皮", "卞", "齐", "康", "伍", "余", "元", "卜", "顾", "孟", "平", "黄",
  "和", "穆", "萧", "尹", "姚", "邵", "湛", "汪", "祁", "毛", "禹", "狄", "米", "贝", "明", "臧",
  "计", "伏", "成", "戴", "谈", "宋", "茅", "庞", "熊", "纪", "舒", "屈", "项", "祝", "董", "梁",
  "杜", "阮", "蓝", "闽", "席", "季", "麻", "强", "贾", "路", "娄", "危", "江", "童", "颜", "郭",
  "梅", "盛", "林", "刁", "锺", "徐", "丘", "骆", "高", "夏", "蔡", "田", "樊", "胡", "凌", "霍",
  "虞", "万", "支", "柯", "昝", "管", "卢", "莫", "经", "房", "裘", "缪", "干", "解", "应", "宗",
  "丁", "宣", "贲", "邓", "郁", "单", "杭", "洪", "包", "诸", "左", "石", "崔", "吉", "钮", "龚",
  "程", "嵇", "邢", "滑", "裴", "陆", "荣", "翁", "荀", "羊", "於", "惠", "甄", "麹", "家", "封",
  "芮", "羿", "储", "靳", "汲", "邴", "糜", "松", "井", "段", "富", "巫", "乌", "焦", "巴", "弓",
  "牧", "隗", "山", "谷", "车", "侯", "宓", "蓬", "全", "郗", "班", "仰", "秋", "仲", "伊", "宫",
  "宁", "仇", "栾", "暴", "甘", "斜", "厉", "戎", "祖", "武", "符", "刘", "景", "詹", "束", "龙",
  "叶", "幸", "司", "韶", "郜", "黎", "蓟", "薄", "印", "宿", "白", "怀", "蒲", "邰", "从", "鄂",
  "索", "咸", "籍", "赖", "卓", "蔺", "屠", "蒙", "池", "乔", "阴", "郁", "胥", "能", "苍", "双",
  "闻", "莘", "党", "翟", "谭", "贡", "劳", "逄", "姬", "申", "扶", "堵", "冉", "宰", "郦", "雍",
  "郤", "璩", "桑", "桂", "濮", "牛", "寿", "通", "边", "扈", "燕", "冀", "郏", "浦", "尚", "农",
  "温", "别", "庄", "晏", "柴", "瞿", "阎", "充", "慕", "连", "茹", "习", "宦", "艾", "鱼", "容",
  "向", "古", "易", "慎", "戈", "廖", "庾", "终", "暨", "居", "衡", "步", "都", "耿", "满", "弘",
  "匡", "国", "文", "寇", "广", "禄", "阙", "东", "欧", "殳", "沃", "利", "蔚", "越", "夔", "隆",
  "师", "巩", "厍", "聂", "晁", "勾", "敖", "融", "冷", "訾", "辛", "阚", "那", "简", "饶", "空",
  "曾", "毋", "沙", "乜", "养", "鞠", "须", "丰", "巢", "关", "蒯", "相", "查", "后", "荆", "红",
  "游", "竺", "权", "逑", "盖", "益", "桓", "公", "仉", "督", "晋", "楚", "阎", "法", "汝", "鄢",
  "涂", "钦", "岳", "帅", "缑", "亢", "况", "后", "有", "琴", "归", "海", "墨", "哈", "谯", "笪",
  "年", "爱", "阳", "佟", "商", "牟", "佘", "佴", "伯", "赏",
  "万俟", "司马", "上官", "欧阳", "夏侯", "诸葛", "闻人", "东方", "赫连", "皇甫", "尉迟", "公羊",
  "澹台", "公冶", "宗政", "濮阳", "淳于", "单于", "太叔", "申屠", "公孙", "仲孙", "轩辕", "令狐",
  "锺离", "宇文", "长孙", "慕容", "鲜于", "闾丘", "司徒", "司空", "丌官", "司寇", "子车", "微生",
  "颛孙", "端木", "巫马", "公西", "漆雕", "乐正", "壤驷", "公良", "拓拔", "夹谷", "宰父", "谷梁",
  "段干", "百里", "东郭", "南门", "呼延", "羊舌", "梁丘", "左丘", "东门", "西门", "南宫"};

        /// <summary>
        /// 静态构造函数 初始化部分数据
        /// </summary>
        static RandomGeneratorUtil()
        {
            Initialization();
        }

        /// <summary>
        /// 随机类型字典集合
        /// </summary>
        internal static Dictionary<string, RandomType> RandomTypeDic { get; set; }

        /// <summary>
        /// 特定随机类型字典集合
        /// </summary>
        internal static Dictionary<string, RandomSpecialType> SpecialRules { get; set; }

        /// <summary>
        /// 常见中文字集合
        /// </summary>
        private static HashSet<char> FrequentChineseChars { get; set; }

        /// <summary>
        /// 手机号开始三位集合
        /// </summary>
        private static string[] telStarts { get; set; }

        /// <summary>
        /// 初始化方法（仅需调用一次）
        /// </summary>
        public static void Init()
        {
        }

        private static void Initialization()
        {
            telStarts = "134,135,136,137,138,139,150,151,152,157,158,159,130,131,132,155,156,133,153,180,181,182,183,185,186,176,187,188,189,177,178".Split(',');
            var randomTypes = Enum.GetValues(typeof(RandomType)).Cast<RandomType>().ToList();
            RandomTypeDic = new Dictionary<string, RandomType>();
            randomTypes.ForEach(e => RandomTypeDic.Add(e.EnumDescription(), e));
            SpecialRules = new Dictionary<string, RandomSpecialType>();
            var list = Enum.GetValues(typeof(RandomSpecialType)).Cast<RandomSpecialType>().ToList();
            list.ForEach(t => SpecialRules.Add(t.EnumDescription(), t));
            if (FrequentChineseChars == null || FrequentChineseChars.Count == 0)
            {
                FrequentChineseChars = GetGB2312String();
            }
        }

        #region 内部函数

        /// <summary>
        /// 获取整个GB2312汉字集合
        /// </summary>
        /// <returns></returns>
        private static HashSet<char> GetGB2312String()
        {
            var list = new HashSet<char>();
            var encoding = Encoding.GetEncoding("GB2312");
            for (var area = 16; area <= 55; area++)
            {
                int len = area == 55 ? 89 : 94;
                for (int j = 0; j <= len; j++)
                {
                    byte[] buff = new byte[2]
                    {
                        (byte)(area + 0xA0),
                        (byte)(j + 0xA0),
                    };
                    var str = encoding.GetString(buff);
                    for (int i = 0; i < str.Length; i++)
                    {
                        list.Add(str[i]);
                    }
                }
            }
            list.ExceptWith("匕刁丐歹戈夭仑讥冗邓艾夯凸卢叭叽皿凹囚矢乍尔冯玄邦迂邢芋芍吏夷吁吕吆" +
          "屹廷迄臼仲伦伊肋旭匈凫妆亥汛讳讶讹讼诀弛阱驮驯纫玖玛韧抠扼汞扳抡坎坞抑拟抒芙芜苇芥芯芭杖杉巫" +
          "杈甫匣轩卤肖吱吠呕呐吟呛吻吭邑囤吮岖牡佑佃伺囱肛肘甸狈鸠彤灸刨庇吝庐闰兑灼沐沛汰沥沦汹沧沪忱" +
          "诅诈罕屁坠妓姊妒纬玫卦坷坯拓坪坤拄拧拂拙拇拗茉昔苛苫苟苞茁苔枉枢枚枫杭郁矾奈奄殴歧卓昙哎咕呵" +
          "咙呻咒咆咖帕账贬贮氛秉岳侠侥侣侈卑刽刹肴觅忿瓮肮肪狞庞疟疙疚卒氓炬沽沮泣泞泌沼怔怯宠宛衩祈诡" +
          "帚屉弧弥陋陌函姆虱叁绅驹绊绎契贰玷玲珊拭拷拱挟垢垛拯荆茸茬荚茵茴荞荠荤荧荔栈柑栅柠枷勃柬砂泵" +
          "砚鸥轴韭虐昧盹咧昵昭盅勋哆咪哟幽钙钝钠钦钧钮毡氢秕俏俄俐侯徊衍胚胧胎狰饵峦奕咨飒闺闽籽娄烁炫" +
          "洼柒涎洛恃恍恬恤宦诫诬祠诲屏屎逊陨姚娜蚤骇耘耙秦匿埂捂捍袁捌挫挚捣捅埃耿聂荸莽莱莉莹莺梆栖桦" +
          "栓桅桩贾酌砸砰砾殉逞哮唠哺剔蚌蚜畔蚣蚪蚓哩圃鸯唁哼唆峭唧峻赂赃钾铆氨秫笆俺赁倔殷耸舀豺豹颁胯" +
          "胰脐脓逛卿鸵鸳馁凌凄衷郭斋疹紊瓷羔烙浦涡涣涤涧涕涩悍悯窍诺诽袒谆祟恕娩骏琐麸琉琅措捺捶赦埠捻" +
          "掐掂掖掷掸掺勘聊娶菱菲萎菩萤乾萧萨菇彬梗梧梭曹酝酗厢硅硕奢盔匾颅彪眶晤曼晦冕啡畦趾啃蛆蚯蛉蛀" +
          "唬啰唾啤啥啸崎逻崔崩婴赊铐铛铝铡铣铭矫秸秽笙笤偎傀躯兜衅徘徙舶舷舵敛翎脯逸凰猖祭烹庶庵痊阎阐" +
          "眷焊焕鸿涯淑淌淮淆渊淫淳淤淀涮涵惦悴惋寂窒谍谐裆袱祷谒谓谚尉堕隅婉颇绰绷综绽缀巢琳琢琼揍堰揩" +
          "揽揖彭揣搀搓壹搔葫募蒋蒂韩棱椰焚椎棺榔椭粟棘酣酥硝硫颊雳翘凿棠晰鼎喳遏晾畴跋跛蛔蜒蛤鹃喻啼喧" +
          "嵌赋赎赐锉锌甥掰氮氯黍筏牍粤逾腌腋腕猩猬惫敦痘痢痪竣翔奠遂焙滞湘渤渺溃溅湃愕惶寓窖窘雇谤犀隘" +
          "媒媚婿缅缆缔缕骚瑟鹉瑰搪聘斟靴靶蓖蒿蒲蓉楔椿楷榄楞楣酪碘硼碉辐辑频睹睦瞄嗜嗦暇畸跷跺蜈蜗蜕蛹" +
          "嗅嗡嗤署蜀幌锚锥锨锭锰稚颓筷魁衙腻腮腺鹏肄猿颖煞雏馍馏禀痹廓痴靖誊漓溢溯溶滓溺寞窥窟寝褂裸谬" +
          "媳嫉缚缤剿赘熬赫蔫摹蔓蔗蔼熙蔚兢榛榕酵碟碴碱碳辕辖雌墅嘁踊蝉嘀幔镀舔熏箍箕箫舆僧孵瘩瘟彰粹漱" +
          "漩漾慷寡寥谭褐褪隧嫡缨撵撩撮撬擒墩撰鞍蕊蕴樊樟橄敷豌醇磕磅碾憋嘶嘲嘹蝠蝎蝌蝗蝙嘿幢镊镐稽篓膘" +
          "鲤鲫褒瘪瘤瘫凛澎潭潦澳潘澈澜澄憔懊憎翩褥谴鹤憨履嬉豫缭撼擂擅蕾薛薇擎翰噩橱橙瓢蟥霍霎辙冀踱蹂" +
          "蟆螃螟噪鹦黔穆篡篷篙篱儒膳鲸瘾瘸糙燎濒憾懈窿缰壕藐檬檐檩檀礁磷瞭瞬瞳瞪曙蹋蟋蟀嚎赡镣魏簇儡徽" +
          "爵朦臊鳄糜癌懦豁臀藕藤瞻嚣鳍癞瀑襟璧戳攒孽蘑藻鳖蹭蹬簸簿蟹靡癣羹鬓攘蠕巍鳞糯譬霹躏髓蘸镶瓤矗");
            return list;
        }

        /// <summary>
        /// 根据指定规则产生随机字符串
        /// </summary>
        /// <param name="rule"></param>
        /// <returns></returns>
        private static string RandomSpecialString(string rule)
        {
            string res = null;
            if (!string.IsNullOrEmpty(rule) && SpecialRules.ContainsKey(rule))
            {
                switch (SpecialRules[rule])
                {
                    case RandomSpecialType.CellPhoneNumber:
                        res = RandomCellPhoneNumber();
                        break;

                    case RandomSpecialType.IdentNumber:
                        res = RandomIdentNumber();
                        break;

                    case RandomSpecialType.ChineseName:
                        res = RandomChineseName();
                        break;

                    default:
                        break;
                }
            }
            return res;
        }

        #endregion 内部函数

        #region 开放函数

        private static readonly string[] ID_Provience =
                {
            "11",
            "12",
            "13",
            "14",
            "15",
            "21",
            "22",
            "23",
            "31",
            "32",
            "33",
            "34",
            "35",
            "36",
            "37",
            "41",
            "42",
            "43",
            "44",
            "45",
            "46",
            "50",
            "51",
            "52",
            "53",
            "54",
            "61",
            "62",
            "63",
            "64",
            "65",
        };

        /// <summary>
        /// 生成随机规则字符串
        /// </summary>
        /// <param name="type"></param>
        /// <param name="length"></param>
        /// <param name="specialStr"></param>
        /// <returns></returns>
        public static string CreateRandomRule(RandomType type, int length, string specialStr = "")
        {
            length = length <= 0 ? 1 : length;
            string rule = "";
            foreach (var item in RandomTypeDic)
            {
                if (type.Contains(item.Value))
                {
                    rule += item.Key + ",";
                }
            }
            if (rule.EndsWith(","))
            {
                rule = rule.Remove(rule.Length - 1, 1);
                if (type.Contains(RandomType.Special))
                {
                    rule += "-" + specialStr;
                }
                else
                {
                    rule += "-" + length;
                }
            }
            return rule;
        }

        /// <summary>
        /// 根据随机规则字符串生成随机字符串
        /// </summary>
        /// <param name="rule"></param>
        /// <returns></returns>
        public static string GenerateString(string rule)
        {
            if (string.IsNullOrEmpty(rule))
                return null;
            var tuple = ParseRandomRule(rule);
            if (tuple == null)
            {
                return null;
            }
            string res = null;
            if (tuple.Item1.Contains(RandomType.Special))
            {
                res = RandomSpecialString(tuple.Item3);
            }
            else
            {
                bool hasNum = tuple.Item1.Contains(RandomType.Number);
                bool hasAlp = tuple.Item1.Contains(RandomType.Alphabet);
                bool hasChi = tuple.Item1.Contains(RandomType.Chinese);
                if (hasChi)
                {
                    res = RandomFrequentChinese(tuple.Item2);
                }
                if (hasNum || hasAlp)
                {
                    res = RandomString(tuple.Item2, hasNum, hasAlp, hasAlp, false, res);
                }
            }
            return res;
        }

        /// <summary>
        /// 获取特定随机字符关键词列表
        /// </summary>
        /// <returns></returns>
        public static IList<string> GetRandomSpecialList()
        {
            string[] res = new string[SpecialRules.Count];
            Array.Copy(SpecialRules.Keys.ToArray(), 0, res, 0, res.Length);
            return res.ToList();
        }

        /// <summary>
        /// 解析随机规则字符串
        /// </summary>
        /// <param name="rule"></param>
        /// <returns></returns>
        public static Tuple<RandomType, int, string> ParseRandomRule(string rule)
        {
            if (string.IsNullOrEmpty(rule))
                return null;
            var rules = rule.Split('-');
            if (rules.Length == 2)
            {
                var types = rules[0].Split(',');
                RandomType type = RandomType.None;
                for (int i = 0; i < types.Length; i++)
                {
                    if (RandomTypeDic.ContainsKey(types[i]))
                    {
                        type |= RandomTypeDic[types[i]];
                    }
                }
                string str = "";
                int len = 0;
                if (type.Contains(RandomType.Special))
                {
                    str = rules[1];
                }
                else
                {
                    int v = 1;
                    int.TryParse(rules[1], out v);
                    len = v;
                }
                return new Tuple<RandomType, int, string>(type, len, str);
            }
            else
            {
                Trace.WriteLine("随机规则解析失败：" + rule);
            }
            return null;
        }

        /// <summary>
        /// 产生随机的手机号
        /// </summary>
        /// <returns></returns>
        public static string RandomCellPhoneNumber()
        {
            byte[] b = new byte[4];
            new RNGCryptoServiceProvider().GetBytes(b);
            Random ran = new Random(BitConverter.ToInt32(b, 0));
            string first = telStarts[ran.Next(0, telStarts.Length - 1)];
            string second = ran.Next(0, 9999).ToString().PadRight(4, '0');
            string thrid = ran.Next(0, 9999).ToString().PadRight(4, '0');
            return first + second + thrid;
        }

        /// <summary>
        /// 生成随机汉字
        /// </summary>
        /// <param name="charLen"></param>
        /// <returns></returns>
        public static string RandomChinese(int charLen = 2)
        {
            int area, code;
            //汉字由区位和码位组成(都为0-94,其中区位16-55为一级汉字区,56-87为二级汉字区,1-9为特殊字符区)
            StringBuilder strtem = new StringBuilder();
            var encoding = Encoding.GetEncoding("GB2312");
            byte[] b = new byte[4];
            for (int i = 0; i < charLen; i++)
            {
                new RNGCryptoServiceProvider().GetBytes(b);
                Random rand = new Random(BitConverter.ToInt32(b, 0));
                area = rand.Next(40) + 16;
                //第55区只有89个字符
                int max = area == 55 ? 89 : 94;
                code = rand.Next(1, max);
                //高字节 = 区号 + 0xA0 低字节 = 位号 + 0xA0
                byte[] buff = new byte[2]
                {
                    Convert.ToByte(area + 0xA0),
                    Convert.ToByte(code + 0xA0)
                };
                strtem.Append(encoding.GetString(buff));
            }
            return strtem.ToString();
        }

        /// <summary>
        /// 产生随机汉字 姓名
        /// </summary>
        /// <returns></returns>
        public static string RandomChineseName()
        {
            byte[] b = new byte[4];
            new RNGCryptoServiceProvider().GetBytes(b);
            Random random = new Random(BitConverter.ToInt32(b, 0));
            int index = random.Next(0, Surnames.Count());
            var surname = Surnames[index];
            var name = RandomChinese();
            return surname + name + "UI";
        }

        /// <summary>
        /// 随机常见中文字符串
        /// </summary>
        /// <param name="len"></param>
        /// <returns></returns>
        public static string RandomFrequentChinese(int len)
        {
            var str = "";
            byte[] b = new byte[4];
            new RNGCryptoServiceProvider().GetBytes(b);
            Random rand = new Random(BitConverter.ToInt32(b, 0));
            for (int i = 0; i < len; i++)
            {
                var c = FrequentChineseChars.ElementAt(rand.Next(0, FrequentChineseChars.Count));
                str += c;
            }
            return str;
        }

        /// <summary>
        /// 产生随机的身份证号
        /// </summary>
        /// <returns></returns>
        public static string RandomIdentNumber(int miniAge = 16, int maxAge = 66)
        {
            StringBuilder bu = new StringBuilder();
            byte[] b = new byte[4];
            new RNGCryptoServiceProvider().GetBytes(b);
            Random rd = new Random(BitConverter.ToInt32(b, 0));
            maxAge = maxAge <= 0 ? 1 : maxAge;
            int age = 18;
            if (miniAge > maxAge)
            {
                miniAge = maxAge;
                age = miniAge;
            }
            else
            {
                age = rd.Next(miniAge, maxAge);
            }
            int year = DateTime.Now.Year - age;
            var month = rd.Next(1, 12);
            bool isLeapYear = year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
            int[] days = new int[12] { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
            if (isLeapYear)
            {
                days[1] = 29;
            }
            int day = rd.Next(1, days[month - 1]);
            //6位地区号 第1位是 1 - 8 第2-6位取随机值
            bu.Append(ID_Provience[rd.Next(0, ID_Provience.Length - 1)]);
            bu.Append(rd.Next(1, 9999).ToString().PadRight(4, '0'));
            bu.Append(year);
            bu.Append(month.ToString().PadLeft(2, '0'));
            bu.Append(day.ToString().PadLeft(2, '0'));
            bu.Append(rd.Next(1, 999).ToString().PadLeft(3, '0'));
            int[] c = { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 };
            char[] r = { '1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2' };
            string convert = bu.ToString();
            int it = 0;
            int res = 0;
            while (it < 17)
            {
                res = res + (convert[it] - '0') * c[it];
                it++;
            }
            int i = res % 11;
            bu.Append(r[i]);
            return bu.ToString();
        }

        ///<summary>
        ///生成随机字符串
        ///</summary>
        ///<param name="length">目标字符串的长度</param>
        ///<param name="useNum">是否包含数字，1=包含，默认为包含</param>
        ///<param name="useLow">是否包含小写字母，1=包含，默认为包含</param>
        ///<param name="useUpp">是否包含大写字母，1=包含，默认为包含</param>
        ///<param name="useSpe">是否包含特殊字符，1=包含，默认为不包含</param>
        ///<param name="custom">要包含的自定义字符，直接输入要包含的字符列表</param>
        ///<returns>指定长度的随机字符串</returns>
        public static string RandomString(int length, bool useNum, bool useLow, bool useUpp, bool useSpe, string custom)
        {
            byte[] b = new byte[4];
            new RNGCryptoServiceProvider().GetBytes(b);
            Random r = new Random(BitConverter.ToInt32(b, 0));
            string s = null;
            List<char> str = new List<char>();
            if (custom != null)
            {
                str.AddRange(custom);
            }
            if (useNum == true)
            {
                str.AddRange("0123456789");
            }
            if (useLow == true)
            {
                str.AddRange("abcdefghijklmnopqrstuvwxyz");
            }
            if (useUpp == true)
            {
                str.AddRange("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
            }
            if (useSpe == true)
            {
                str.AddRange("!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~");
            }
            for (int i = 0; i < length; i++)
            {
                s += str[r.Next(0, str.Count - 1)];
            }
            return s;
        }

        #endregion 开放函数
    }
}